<?php
use app\Normal;
use think\facade\Cache;
use app\common\service\RpcService\RpcClient\TcpSocketClientService;
// 应用公共文件
/**
 * 属性对象
 * 通过反射机制获取类属性
 * @param string $className
 * @param string $callMethod
 * @param $parameters
 */
function callApi( string $className , string $callMethod, $parameters )
{
    $reflect = new \ReflectionClass($className);
    if( ! $reflect->hasMethod($callMethod) ) {
        return Normal::returnCode(Normal::FAIL,"服务类【{$className}】方法【{$callMethod}】不存在");
    }
    $reft = $reflect->newInstance();
    return $reft->{$callMethod}($parameters);
}

/**
 * 调用tcp 服务
 * @param string $service
 * @param array $args
 */
function callTcpService( string $service ,array $args = [] )
{
    return (new TcpSocketClientService())->send($service,$args);
}

/**
 * restFulApi 响应
 * @param array $result
 * $result['code'] = 200,0,201,400,500,401,301......
 * $result['msg']  = 响应信息
 * $result['data'] = array;
 * 注意：
 * 1、如果要全局统一响应输出restFulApi标准格式,默认.env文件中RESPONSE_MODE=RESTFULAPI
 * 2、如果要全局统一响应输出JSON {"code":"200","msg":"返回信息","data":"返回数据对象"} ，需要修改.env文件中RESPONSE_MODE=JSON
 */
function apiResponse( array $result )
{
    if( env('APP.RESPONSE_MODE') == 'JSON' ) {
        return json($result);
    }
    
    $code = $result['code'] == 0 ? 400 : $result['code'];
    if( $code == 200 ) {
        return json($result['data'])->code($code)->header([
            'Cache-control' => 'no-cache,must-revalidate'
        ]);
    } else {
        return response($result['msg'])->code($code);
    }
}

/**
 * 获取redis对象
 */
function getRedisObj()
{
    return Cache::store('redis')->handler();
}

/**
 *@des      一维数组生成多维数组(树形)
 *@param    array  $arr   数组
 *@param    int    $pid   父id
 *@param    string $id_k  主键字段
 *@param    string $pid_k 父id字段
 *@return   array
 */
if (!function_exists('tree')) {
    function tree($arr, $pid, $id_k, $pid_k,$top=false,$child_name = 'son')
    {
        $tree = $top?$top:array();
        foreach ($arr as $k => $v) {
            if ($v[$pid_k] == $pid) {
                unset($arr[$k]);
                $temp = $v;
                $temp[$child_name] = tree($arr, $v[$id_k], $id_k, $pid_k);

                if (!$temp[$child_name]) {
                    unset($temp[$child_name]);
                }
                $tree[] = $temp;
            }
        }
        return $tree;
    }
}

/**
 * 组装参数
 */
if (!function_exists('getSignContent')) {
    function getSignContent($data): string
    {
        $buff = '';
        foreach ($data as $k => $v) {
            $buff .= ($k != 'sign' && $v != '' && !is_array($v)) ? $k.'='.$v.'&' : '';
        }
        return trim($buff, '&');
    }
}
/**
 * C扩展xlsxwriter
 * @param array $header
 * @param array $data
 * @param string $fileName
 * @param string $host
 * @return string
 */
function xlsxFileLocalStorage ( array $header , array $data , string $fileName,string $host,bool $isDelete = true )
{
	static $tmpDir;
	if(is_null($tmpDir)) {
		$tmpDir = getTmpDir();
	}

    $config = [
        'path' => $tmpDir . '/',
    ];

    //初始化对象
    $fileName = $fileName."-".date("YmdHis").".xlsx";
    $xlsxObject = new \Vtiful\Kernel\Excel($config);
    $xlsxObject->fileName($fileName);
    $fileHandle = $xlsxObject->getHandle();

    //初始化格式
    $format = new \Vtiful\Kernel\Format($fileHandle);
    $boldStyle = $format->bold()->toResource();
    $rowStyle = $format
    ->bold()
    ->align(\Vtiful\Kernel\Format::FORMAT_ALIGN_CENTER, \Vtiful\Kernel\Format::FORMAT_ALIGN_VERTICAL_CENTER)
    ->toResource();

    //输出文件地址
    $filePath = $xlsxObject->header($header)->data($data)->output();

    //写入本地指定文件
    $movePath  = 'websocketservice';
    $savePath  = __DIR__.'/../public/'.$movePath;
    if( !is_dir($savePath) ) {
        mkdir($savePath, 0777, true);
    }
    chmod($savePath, 0777);

    //删除指定目录下指定日期之前的所有数据
    if( $isDelete ) {
        deleteDirFileByDays($savePath);
    }

    //开始准备生成文件目录
    $endSavePathName = $savePath."/".$fileName;
    copy($filePath,$endSavePathName);

    //返回前端下载文件地址
    $host = $host ??'';
    $httptype=env('APP_SOCKET_HTTP_TYPE','http');
    return "{$httptype}://{$host}/".$movePath."/".$fileName;
}

/**
 * 删除指定目录下指定日期之前的所有数据
 * @param string $dir
 * @param number $times
 */
function deleteDirFileByDays( $path , $times = 3600 )
{
    if( is_dir($path) ) {
        if( $dh = opendir($path) ) {
            while ( false !== ( $file = readdir($dh) ) ) {
                if( !in_array($file, ['.','..']) ) {
                    $fullpath           = $path."/".$file;
                    $filedate           = date("YmdHis",filemtime($fullpath));
                    $file_start_time    = strtotime($filedate);
                    $now_start_time     = strtotime(date("YmdHis"));
                    $micstime           = $now_start_time - $file_start_time;
                    if( $micstime >= $times ) {
                        echo "delete file 【{$fullpath}】 success".PHP_EOL;
                        @unlink($fullpath);
                    }
                }
            }
        }
    }
}
function getTmpDir(): string
{
	$tmp = ini_get('upload_tmp_dir');

	if ($tmp !== False && file_exists($tmp)) {
		return realpath($tmp);
	}

	return realpath(sys_get_temp_dir());
}
/*
 * 读取excel
 * **/
function ExcelImport($filename, $exts='xls',$key=2)
    {
        //导入PHPExcel类库，因为PHPExcel没有用命名空间，只能inport导入
       // Loader::import("PHPExcel.Classes.PHPExcel");
        require app()->getRootPath() .'/extend/PHPExcel/Classes/PHPExcel.php';
        //创建PHPExcel对象，注意，不能少了\
        $PHPExcel=new \PHPExcel();
        //如果excel文件后缀名为.xls，导入这个类
        if($exts == 'xls'){
            //Loader::import("PHPExcel.Classes.PHPExcel.Reader.Excel5");
            require app()->getRootPath() .'/extend/PHPExcel/Classes/PHPExcel/Reader/Excel5.php';
            $PHPReader=new \PHPExcel_Reader_Excel5();
        }else if($exts == 'xlsx'){
            //Loader::import("PHPExcel.Classes.PHPExcel.Reader.Excel2007");
            require app()->getRootPath() .'/extend/PHPExcel/Classes/PHPExcel/Reader/Excel2007.php';
            $PHPReader=new \PHPExcel_Reader_Excel2007();
                //载入文件
        }

        $PHPExcel=$PHPReader->load($filename);
        //获取表中的第一个工作表，如果要获取第二个，把0改为1，依次类推
        $currentSheet=$PHPExcel->getSheet(0);
        //获取总列数
        $allColumn=$currentSheet->getHighestColumn();
        //获取总行数
        $allRow=$currentSheet->getHighestRow();
        $data = [];
        //循环获取表中的数据，$currentRow表示当前行，从哪行开始读取数据，索引值从0开始
        for($currentRow=$key;$currentRow<=$allRow;$currentRow++){
            //从哪列开始，A表示第一列
            for($currentColumn='A';$currentColumn<=$allColumn;$currentColumn++){
                //数据坐标
                $address=$currentColumn.$currentRow;
                //读取到的数据，保存到数组$arr中
                $cell =$currentSheet->getCell($address)->getCalculatedValue();
                //$cell = $data[$currentRow][$currentColumn];
                if($cell instanceof PHPExcel_RichText){
                    $cell  = $cell->__toString();
                }
                if(empty($data[$currentRow])){
                    $data[$currentRow] = [];
                }
                $data[$currentRow][]=$cell;
            }
        }
        return $data;
    }
